﻿using System;
using System.Collections.Generic;
using DM4;
using DM4.InfoClasses;
using sscore;

namespace DMN_MailListener
{

    public class DMN_MailListener : DaemonBase, IDisposable
    {
        private Worker _worker;
        public DMN_MailListener()
        {
            Version = "1.0";
            ModuleCode = MailListenerConsts.ModuleCode;
            Description = "Check mail module";
            Debug = true;
        }

        public override OperationResult Init(IDM4Core iCore, DmTaskParams param = null)
        {
            base.Init(iCore, param);

            WriteLog(String.Format("Initialize daemon [{0}]...", ModuleCode));
            WriteLog(String.Format("Initialize daemon [{0}] complete", ModuleCode));
                   
            WriteLog("Initialize module, create worker instance");
            _worker = new Worker(WriteLog, OnWorkerResult, Core.GetSysParam(DM4Consts.ConnectionString));

            return new OperationResult { Result = DM4Consts.Ok };
        }

        public override OperationResult Start()
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };
            WriteLog(String.Format("Start daemon [{0}] ...", ModuleCode));
            base.Start();

            Status = DaemonStatus.Starting;
            try
            {
                WorkWithDbData db = new WorkWithDbData(Core.GetSysParam(DM4Consts.ConnectionString), WriteLog);
                _worker.Check(db.GetNotEndedCheck());
                Status = DaemonStatus.Run;
            }
            catch (Exception ex)
            {
                WriteLog(String.Format("Error occurred while start [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                or.Result = DM4Consts.ErrorUnknown;
                or.Message = ex.Message;
                Status = DaemonStatus.Stop;
            }

            return or;
        }

        public override OperationResult Execute(string cmdName, object commandParameters)
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };

            if (cmdName.ToUpper() == MailListenerCommands.CheckMail.ToUpper())
            {
                if (commandParameters is List<MailListenerParameters> || commandParameters is MailListenerParameters)
                {
                    try
                    {
                        if (commandParameters is List<MailListenerParameters>)
                            _worker.Start((List<MailListenerParameters>)commandParameters);
                        else
                            _worker.Start(new List<MailListenerParameters> { (MailListenerParameters)commandParameters });
                    }
                    catch (Exception ex)
                    {
                        WriteLog(String.Format("Error occurred while Execute [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                        Status = DaemonStatus.Stop;
                    }
                }
                else
                {
                    or.Result = DM4Consts.ErrorUnknownEntity;
                    or.Message = "Invalid parameters type, must be passed List<MailListenerParameters> or MailListenerParameters class instance.";
                }
            }
            else
            {
                or.Result = DM4Consts.ErrorUnknownCommand;
                or.Message = String.Format("Invalid command name for {0}.", ModuleCode);
            }
            return or;
        }

        public void OnWorkerResult(WorkerResult wr)
        {
         //   WriteLog(string.Format("Mail check complete. Processed mail(s) [{0}], errors count [{1}]", wr.CompleteCount, wr.ErrorCount));
            WriteLog(string.Format("Mail check complete. Processed mail(s) [{0}]", wr.CompleteCount));
        }       

        public override OperationResult Stop()
        {
            WriteLog(String.Format("Stop daemon [{0}] ...", ModuleCode));
            Status = DaemonStatus.Stopping;
            base.Stop();

            if (_worker != null)
            {
                _worker.Stop();
                _worker = null;
            }
            Status = DaemonStatus.Stop;

            return new OperationResult { Result = DM4Consts.Ok, Message = "" };
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                if (_worker != null)
                {
                    _worker.Dispose();
                    _worker = null;
                }
        }
        ~DMN_MailListener()
        {
            Dispose(false);
        }
    }
}
